@codeyam/codeyam-cli 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/analyzer-template/.build-info.json +6 -6
  2. package/analyzer-template/log.txt +3 -3
  3. package/codeyam-cli/src/commands/editor.js +62 -27
  4. package/codeyam-cli/src/commands/editor.js.map +1 -1
  5. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +440 -1
  6. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
  7. package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js +58 -4
  8. package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js.map +1 -1
  9. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +76 -0
  10. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -1
  11. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js +139 -1
  12. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js.map +1 -1
  13. package/codeyam-cli/src/utils/backgroundServer.js +1 -1
  14. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  15. package/codeyam-cli/src/utils/editorAudit.js +107 -6
  16. package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
  17. package/codeyam-cli/src/utils/editorEntityHelpers.js +18 -3
  18. package/codeyam-cli/src/utils/editorEntityHelpers.js.map +1 -1
  19. package/codeyam-cli/src/utils/editorScenarios.js +10 -1
  20. package/codeyam-cli/src/utils/editorScenarios.js.map +1 -1
  21. package/codeyam-cli/src/utils/scenariosManifest.js +30 -0
  22. package/codeyam-cli/src/utils/scenariosManifest.js.map +1 -1
  23. package/codeyam-cli/src/webserver/backgroundServer.js +42 -57
  24. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  25. package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-CzTDWkF2.js → CopyButton-CLe80MMu.js} +1 -1
  26. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-BFbq6iFk.js → EntityItem-Crt_KN_U.js} +1 -1
  27. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-B6OMi58N.js → EntityTypeIcon-CD7lGABo.js} +1 -1
  28. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-DuYodzo1.js → InlineSpinner-CgTNOhnu.js} +1 -1
  29. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CXo9EeCl.js → InteractivePreview-CKeQT5Ty.js} +2 -2
  30. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-DYCNb2It.js → LibraryFunctionPreview-D3s1MFkb.js} +1 -1
  31. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-CZgY3sxX.js → LogViewer-CM5zg40N.js} +1 -1
  32. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-CnYYwRDw.js → ReportIssueModal-C2PLkej3.js} +1 -1
  33. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-CDoF7ZpU.js → SafeScreenshot-DanvyBPb.js} +1 -1
  34. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DrnfvaLL.js → ScenarioViewer-DUMfcNVK.js} +1 -1
  35. package/codeyam-cli/src/webserver/build/client/assets/{Spinner-Df3UCi8k.js → Spinner-D0LgAaSa.js} +1 -1
  36. package/codeyam-cli/src/webserver/build/client/assets/{ViewportInspectBar-DRKR9T0U.js → ViewportInspectBar-BA_Ry-rs.js} +1 -1
  37. package/codeyam-cli/src/webserver/build/client/assets/{_index-ClR-g3tY.js → _index-BAWd-Xjf.js} +1 -1
  38. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-DTH6ydEA.js → activity.(_tab)-BOARiB-g.js} +1 -1
  39. package/codeyam-cli/src/webserver/build/client/assets/{addon-web-links-74hnHF59.js → addon-web-links-CHx25PAe.js} +1 -1
  40. package/codeyam-cli/src/webserver/build/client/assets/{agent-transcripts-B8CYhCO9.js → agent-transcripts-Bg3e7q4S.js} +1 -1
  41. package/codeyam-cli/src/webserver/build/client/assets/{book-open-CLaoh4ac.js → book-open-CL-lMgHh.js} +1 -1
  42. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-BZ2DZxbW.js → chevron-down-GmAjGS9-.js} +1 -1
  43. package/codeyam-cli/src/webserver/build/client/assets/{chunk-JZWAC4HX-BBXArFPl.js → chunk-JZWAC4HX-BAdwhyCx.js} +11 -11
  44. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-CT4unAk-.js → circle-check-DFcQkN5j.js} +1 -1
  45. package/codeyam-cli/src/webserver/build/client/assets/{copy-zK0B6Nu-.js → copy-C6iF61Xs.js} +1 -1
  46. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-DJB0YQJL.js → createLucideIcon-4ImjHTVC.js} +1 -1
  47. package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-CkXFP_i-.js → dev.empty-C8y4mmyv.js} +1 -1
  48. package/codeyam-cli/src/webserver/build/client/assets/editor._tab-Gbk_i5Js.js +1 -0
  49. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-B7xQ9Sjy.js +58 -0
  50. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-CxmrE6AF.js +41 -0
  51. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-BqAN7hyG.js → entity._sha._-Blfy9UlN.js} +1 -1
  52. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.dev-BOi8kpwd.js → entity._sha.scenarios._scenarioId.dev-CUobbQdQ.js} +1 -1
  53. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-Dg1NhIms.js → entity._sha.scenarios._scenarioId.fullscreen-C6eeL24i.js} +1 -1
  54. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-CJX6kkkV.js → entity._sha_.create-scenario-DQM8E7L4.js} +1 -1
  55. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-BhVjZhKg.js → entity._sha_.edit._scenarioId-CAoXLsQr.js} +1 -1
  56. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-_gzKltPN.js → entry.client-SuW9syRS.js} +1 -1
  57. package/codeyam-cli/src/webserver/build/client/assets/{files-CV_17tZS.js → files-D-xGrg29.js} +1 -1
  58. package/codeyam-cli/src/webserver/build/client/assets/{git-D-YXmMbR.js → git-Bq_fbXP5.js} +1 -1
  59. package/codeyam-cli/src/webserver/build/client/assets/globals-fAqOD9ex.css +1 -0
  60. package/codeyam-cli/src/webserver/build/client/assets/{index-CCrgCshv.js → index-Bp1l4hSv.js} +1 -1
  61. package/codeyam-cli/src/webserver/build/client/assets/{index-BsX0F-9C.js → index-CWV9XZiG.js} +1 -1
  62. package/codeyam-cli/src/webserver/build/client/assets/{index-Blo6EK8G.js → index-DE3jI_dv.js} +1 -1
  63. package/codeyam-cli/src/webserver/build/client/assets/{labs-Byazq8Pv.js → labs-B_IX45ih.js} +1 -1
  64. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-DVQ0oHR7.js → loader-circle-De-7qQ2u.js} +1 -1
  65. package/codeyam-cli/src/webserver/build/client/assets/manifest-5d53342d.js +1 -0
  66. package/codeyam-cli/src/webserver/build/client/assets/{memory-b-VmA2Vj.js → memory-Cx2xEx7s.js} +1 -1
  67. package/codeyam-cli/src/webserver/build/client/assets/{pause-DGcndCAa.js → pause-CFxEKL1u.js} +1 -1
  68. package/codeyam-cli/src/webserver/build/client/assets/root-DB3O9_9j.js +67 -0
  69. package/codeyam-cli/src/webserver/build/client/assets/{search-C0Uw0bcK.js → search-BdBb5aqc.js} +1 -1
  70. package/codeyam-cli/src/webserver/build/client/assets/{settings-OoNgHIfW.js → settings-DdE-Untf.js} +1 -1
  71. package/codeyam-cli/src/webserver/build/client/assets/{simulations-Bcemfu8a.js → simulations-DSCdE99u.js} +1 -1
  72. package/codeyam-cli/src/webserver/build/client/assets/{terminal-BgMmG7R9.js → terminal-CrplD4b1.js} +1 -1
  73. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-Cs87hJYK.js → triangle-alert-DqJ0j69l.js} +1 -1
  74. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-BR3Rs7JY.js → useCustomSizes-DhXHbEjP.js} +1 -1
  75. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-BxxP_XF9.js → useLastLogLine-BNd5hYuW.js} +1 -1
  76. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-BermyNU5.js → useReportContext-Cy5Qg_UR.js} +1 -1
  77. package/codeyam-cli/src/webserver/build/client/assets/{useToast-a_QN_W9_.js → useToast-5HR2j9ZE.js} +1 -1
  78. package/codeyam-cli/src/webserver/build/server/assets/{analysisRunner-lv2ooewK.js → analysisRunner-DcJSnBCE.js} +1 -1
  79. package/codeyam-cli/src/webserver/build/server/assets/{index-Im3Smyei.js → index-CEaDhUiv.js} +1 -1
  80. package/codeyam-cli/src/webserver/build/server/assets/{init-BjuAFKGM.js → init-DA7guOrE.js} +1 -1
  81. package/codeyam-cli/src/webserver/build/server/assets/server-build-juyiY2m6.js +551 -0
  82. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  83. package/codeyam-cli/src/webserver/build-info.json +5 -5
  84. package/codeyam-cli/src/webserver/terminalServer.js +1 -1
  85. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  86. package/codeyam-cli/templates/nextjs-prisma-sqlite/package.json +1 -1
  87. package/codeyam-cli/templates/nextjs-prisma-supabase/package.json +1 -1
  88. package/package.json +1 -1
  89. package/codeyam-cli/src/webserver/build/client/assets/editor._tab-DPw7NZHc.js +0 -1
  90. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-CjC3_6JI.js +0 -58
  91. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-DBa7T2FK.js +0 -41
  92. package/codeyam-cli/src/webserver/build/client/assets/globals-DRvOjyO3.css +0 -1
  93. package/codeyam-cli/src/webserver/build/client/assets/manifest-75b1b319.js +0 -1
  94. package/codeyam-cli/src/webserver/build/client/assets/root-F-k2uYj5.js +0 -67
  95. package/codeyam-cli/src/webserver/build/server/assets/server-build-CNjF0B9B.js +0 -551
@@ -1,10 +1,10 @@
1
1
  {
2
- "buildTimestamp": "2026-03-17T22:42:54.370Z",
3
- "buildTime": 1773787374370,
4
- "gitCommit": "6af1ab46096de2c86af4f0947046703a16ac9786",
2
+ "buildTimestamp": "2026-03-18T20:56:41.501Z",
3
+ "buildTime": 1773867401501,
4
+ "gitCommit": "3328e60080cd05630588c6f1b139c2caffcb164a",
5
5
  "nodeVersion": "v20.20.1",
6
6
  "contentHash": "b046e014847d5b02d10d6795839ccd0d5117627cbd0be413260824610596a63d",
7
- "buildNumber": 1087,
8
- "semanticVersion": "0.1.1087",
9
- "version": "0.1.1087 (2026-03-17T22:42+b046e01)"
7
+ "buildNumber": 1100,
8
+ "semanticVersion": "0.1.1100",
9
+ "version": "0.1.1100 (2026-03-18T20:56+b046e01)"
10
10
  }
@@ -1,7 +1,7 @@
1
1
 
2
- [3/17/2026, 10:42:54 PM] > codeyam-combo@1.0.0 mergeDependencies
3
- [3/17/2026, 10:42:54 PM] > node ./scripts/mergePackageJsonFiles.cjs
2
+ [3/18/2026, 8:56:41 PM] > codeyam-combo@1.0.0 mergeDependencies
3
+ [3/18/2026, 8:56:41 PM] > node ./scripts/mergePackageJsonFiles.cjs
4
4
 
5
5
 
6
- [3/17/2026, 10:42:54 PM] Merged dependencies into root package.json
6
+ [3/18/2026, 8:56:41 PM] Merged dependencies into root package.json
7
7
 
@@ -205,6 +205,8 @@ function checkbox(text) {
205
205
  * Prints seed-based scenarios, mock-based fallback, @ file prefix, externalApis, url requirement, and error checking.
206
206
  */
207
207
  function printAppScenarioInstructions(pageName, route) {
208
+ const root = process.cwd();
209
+ const hasSeedAdapter = !!detectSeedAdapter(root);
208
210
  checkbox('Check existing scenarios: `codeyam editor scenarios`');
209
211
  console.log(chalk.dim(' Review existing scenarios — reuse and update their data rather than'));
210
212
  console.log(chalk.dim(' creating duplicates. Re-register with the same name to update a scenario.'));
@@ -230,10 +232,18 @@ function printAppScenarioInstructions(pageName, route) {
230
232
  console.log(chalk.yellow(' Required fields: "type":"application", "url" (real route), "pageFilePath" (source file)'));
231
233
  console.log(chalk.yellow(' Do NOT include "componentName" — that would make it a component scenario'));
232
234
  console.log();
233
- checkbox('Choose the right data approach for scenarios:');
234
- console.log(chalk.dim(' With seed adapter: add "seed":{...} to populate the database for each state'));
235
- console.log(chalk.dim(' Without seed adapter: add "mockData":{"routes":{"/api/...":{"body":[...]}}} to mock API responses'));
236
- console.log(chalk.dim(' For external APIs (Stripe, weather, etc.): add "externalApis":{"GET https://...":{"body":[...],"status":200}}'));
235
+ if (hasSeedAdapter) {
236
+ checkbox(chalk.bold.red('REQUIRED: Every app scenario MUST include "seed" data without it the page will be empty!'));
237
+ console.log(chalk.yellow(' A seed adapter exists — you MUST include "seed":{...} in every app scenario registration.'));
238
+ console.log(chalk.yellow(' An app scenario without seed data will render an empty page (no database rows = nothing to show).'));
239
+ console.log(chalk.dim(' "seed" maps table names to arrays of rows: "seed":{"user":[{"id":1,"name":"Alice"}],"article":[...]}'));
240
+ console.log(chalk.dim(' For external APIs: also add "externalApis":{"GET https://...":{"body":[...],"status":200}}'));
241
+ }
242
+ else {
243
+ checkbox('Include data in every app scenario — without it the page will be empty:');
244
+ console.log(chalk.dim(' Use "mockData":{"routes":{"/api/...":{"body":[...]}}} to mock API responses'));
245
+ console.log(chalk.dim(' For external APIs: add "externalApis":{"GET https://...":{"body":[...],"status":200}}'));
246
+ }
237
247
  checkbox('For large seed/mock data, write JSON to a temp file and use @ prefix:');
238
248
  console.log(chalk.dim(' Write JSON to .codeyam/tmp/scenario.json then register with:'));
239
249
  console.log(chalk.dim(' codeyam editor register @.codeyam/tmp/scenario.json'));
@@ -320,7 +330,7 @@ function printComponentCaptureInstructions() {
320
330
  console.log(chalk.dim(' The route defines a `scenarios` object mapping scenario names to props,'));
321
331
  console.log(chalk.dim(' reads `?s=ScenarioName` from the URL, and renders the component with those props.'));
322
332
  console.log(chalk.dim(' Wrap the component in a capture container with id="codeyam-capture":'));
323
- console.log(chalk.dim(' <div id="codeyam-capture" style={{ display:"inline-block", padding:"20px" }}>'));
333
+ console.log(chalk.dim(' <div id="codeyam-capture" style={{ display:"inline-block" }}>'));
324
334
  console.log(chalk.dim(' <div style={{ width:"100%", maxWidth:"..." }}> ← match the app\'s container width'));
325
335
  console.log(chalk.dim(' e.g. card in a 3-col grid → maxWidth:"24rem", full-width component → omit maxWidth'));
326
336
  console.log(chalk.dim(' The screenshot captures just this wrapper, so the component fills the image.'));
@@ -1444,8 +1454,6 @@ function printStep12(root, feature) {
1444
1454
  }
1445
1455
  // ─── Step 13: Present ─────────────────────────────────────────────────
1446
1456
  function printStep13(root, feature) {
1447
- const port = getServerPort();
1448
- const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1449
1457
  const prevState = readState(root);
1450
1458
  const isResuming = prevState?.step === 13;
1451
1459
  const now = new Date().toISOString();
@@ -1464,18 +1472,9 @@ function printStep13(root, feature) {
1464
1472
  console.log('Present the results to the user and get their approval.');
1465
1473
  console.log();
1466
1474
  console.log(chalk.bold('Checklist:'));
1467
- checkbox('Fetch all scenarios: `codeyam editor scenarios`');
1468
- console.log(chalk.dim(' Each scenario has a `changeStatus` field: "new", "edited", "impacted", or null.'));
1469
- checkbox('Pick the best scenario to showcase from this working session:');
1470
- console.log(chalk.dim(' Prefer scenarios with changeStatus "new" or "edited" (directly changed in this session).'));
1471
- console.log(chalk.dim(' For app-level scenarios, prefer those showing the new/changed functionality.'));
1472
- console.log(chalk.dim(' NEVER pick a scenario with changeStatus null — those are unchanged from a previous commit.'));
1473
- checkbox('Switch the preview to that scenario using its `id` and `dimension`:');
1474
- console.log(chalk.dim(` codeyam editor preview '{"scenarioId":"<id>","dimension":"${dim}"}'`));
1475
- console.log(chalk.dim(' Use the dimension that matches the scenario — check its registered dimensions.'));
1476
- printDimensionGuidance(dim, dimNames);
1477
1475
  checkbox(`Show the results panel: \`codeyam editor show-results\``);
1478
1476
  console.log(chalk.dim(' This opens a visual panel below the terminal showing all scenarios with screenshots.'));
1477
+ console.log(chalk.dim(' The preview automatically switches to the first app-level scenario.'));
1479
1478
  console.log(chalk.dim(' The user can click scenarios to switch the live preview.'));
1480
1479
  checkbox('Write a 1-2 sentence summary of what was built');
1481
1480
  checkbox('Report test count and audit status (one line)');
@@ -1705,7 +1704,6 @@ function printMigrateStep4(root) {
1705
1704
  }
1706
1705
  const { pageName, pageIndex, totalPages } = pageInfo;
1707
1706
  writeMigrationStepState(root, 4, pageName, pageIndex, totalPages);
1708
- const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1709
1707
  console.log();
1710
1708
  console.log(chalk.bold.cyan(`━━━ Migration Step 4: Preview — ${pageName} (${pageIndex + 1}/${totalPages}) ━━━`));
1711
1709
  console.log();
@@ -1715,11 +1713,8 @@ function printMigrateStep4(root) {
1715
1713
  checkbox('Review all scenario screenshots for this page — do they look correct?');
1716
1714
  checkbox('Check for client errors: `codeyam editor client-errors`');
1717
1715
  checkbox('If any issues: fix the scenario data, re-register affected scenarios');
1718
- checkbox('Fetch all scenarios: `codeyam editor scenarios`');
1719
- checkbox('Pick the best scenario to showcase:');
1720
- console.log(chalk.dim(` codeyam editor preview '{"scenarioId":"<id>","dimension":"${dim}"}'`));
1721
- printDimensionGuidance(dim, dimNames);
1722
1716
  checkbox('Show results: `codeyam editor show-results`');
1717
+ console.log(chalk.dim(' The preview automatically switches to the first app-level scenario.'));
1723
1718
  console.log();
1724
1719
  console.log(chalk.dim('The user should now see their existing page with live screenshots in the preview.'));
1725
1720
  migrationStopGate(4, pageName, pageIndex, totalPages);
@@ -1879,18 +1874,14 @@ function printMigrateStep10(root) {
1879
1874
  }
1880
1875
  const { pageName, pageIndex, totalPages } = pageInfo;
1881
1876
  writeMigrationStepState(root, 10, pageName, pageIndex, totalPages);
1882
- const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1883
1877
  console.log();
1884
1878
  console.log(chalk.bold.cyan(`━━━ Migration Step 10: Present — ${pageName} (${pageIndex + 1}/${totalPages}) ━━━`));
1885
1879
  console.log();
1886
1880
  console.log("Show results and commit this page's migration.");
1887
1881
  console.log();
1888
1882
  console.log(chalk.bold('Checklist:'));
1889
- checkbox('Fetch all scenarios: `codeyam editor scenarios`');
1890
- checkbox('Pick the best scenario to showcase:');
1891
- console.log(chalk.dim(` codeyam editor preview '{"scenarioId":"<id>","dimension":"${dim}"}'`));
1892
- printDimensionGuidance(dim, dimNames);
1893
1883
  checkbox('Show results: `codeyam editor show-results`');
1884
+ console.log(chalk.dim(' The preview automatically switches to the first app-level scenario.'));
1894
1885
  checkbox('Write a 1-2 sentence summary of what was migrated');
1895
1886
  console.log();
1896
1887
  console.log(chalk.bold('Present a selection menu (AskUserQuestion with these EXACT option labels):'));
@@ -2363,6 +2354,8 @@ async function handleAnalyzeImports(options = {}) {
2363
2354
  sha: e.sha,
2364
2355
  name: e.name,
2365
2356
  filePath: e.filePath || '',
2357
+ isDefaultExport: e.metadata?.notExported === false &&
2358
+ e.metadata?.namedExport === false,
2366
2359
  })));
2367
2360
  if (backfillResult.updated > 0 && !options.silent) {
2368
2361
  console.log(chalk.green(`Linked ${backfillResult.updated} scenario(s) to their entities.`));
@@ -2668,6 +2661,13 @@ async function handleRegister(jsonArg) {
2668
2661
  if (data.captureError)
2669
2662
  parts.push(chalk.yellow(`captureError="${data.captureError}"`));
2670
2663
  console.log(prefix + parts.join(' '));
2664
+ // Warn when application scenario is missing seed data
2665
+ if (data.missingSeedWarning) {
2666
+ console.log(chalk.red.bold('WARNING: No seed data in this application scenario!'));
2667
+ console.log(chalk.yellow(' This scenario has type "application" but no "seed" data was provided.'));
2668
+ console.log(chalk.yellow(' The page will render with an empty database — nothing will be visible.'));
2669
+ console.log(chalk.yellow(' Re-register with "seed":{...} containing the database rows this page needs.'));
2670
+ }
2671
2671
  // Surface client errors prominently so they can't be missed
2672
2672
  if (data.clientErrors && data.clientErrors.length > 0) {
2673
2673
  console.log(chalk.red.bold(`⚠ WARNING: ${data.clientErrors.length} client error${data.clientErrors.length !== 1 ? 's' : ''} detected during capture:`));
@@ -2996,6 +2996,8 @@ function printAuditGateFailures(data) {
2996
2996
  issues.push(`${s.functionsMissing} function(s) missing test files`);
2997
2997
  if (s.functionsFailing > 0)
2998
2998
  issues.push(`${s.functionsFailing} function(s) with failing tests`);
2999
+ if (s.functionsRunnerError > 0)
3000
+ issues.push(`${s.functionsRunnerError} function(s) with test runner errors (the runner crashed — not a test failure)`);
2999
3001
  if (s.functionsNameMismatch > 0)
3000
3002
  issues.push(`${s.functionsNameMismatch} function(s) with test name mismatch`);
3001
3003
  if (s.missingFromGlossary > 0)
@@ -3004,6 +3006,8 @@ function printAuditGateFailures(data) {
3004
3006
  issues.push(`${s.incompleteEntities} entity/entities need import analysis`);
3005
3007
  if (s.miscategorizedScenarios > 0)
3006
3008
  issues.push(`${s.miscategorizedScenarios} component(s) using page URLs instead of isolation routes`);
3009
+ if (s.scenariosNeedingRecapture > 0)
3010
+ issues.push(`${s.scenariosNeedingRecapture} scenario(s) need recapture (dependency tree changed)`);
3007
3011
  if (issues.length > 0) {
3008
3012
  console.error(chalk.yellow('\nAudit failures:'));
3009
3013
  for (const issue of issues) {
@@ -3122,6 +3126,14 @@ async function handleAudit() {
3122
3126
  case 'ok':
3123
3127
  detail = chalk.dim(` (${f.testFile})`);
3124
3128
  break;
3129
+ case 'runner_error':
3130
+ detail = chalk.red(` — test runner crashed: ${f.testFile}`);
3131
+ if (f.errorMessage) {
3132
+ detail += `\n ${chalk.red(f.errorMessage)}`;
3133
+ detail += `\n ${chalk.yellow('Note: This is NOT a test failure — the test runner itself could not execute.')}`;
3134
+ detail += `\n ${chalk.yellow('Try running the test manually: npx vitest run ' + f.testFile)}`;
3135
+ }
3136
+ break;
3125
3137
  case 'failing':
3126
3138
  detail = chalk.red(` — tests failing: ${f.testFile}`);
3127
3139
  break;
@@ -3186,6 +3198,19 @@ async function handleAudit() {
3186
3198
  console.log(chalk.yellow(' or re-register with an isolation URL.'));
3187
3199
  console.log();
3188
3200
  }
3201
+ // Scenarios needing recapture (entity or dependency tree changed)
3202
+ const scenariosNeedingRecapture = data.scenariosNeedingRecapture || [];
3203
+ if (scenariosNeedingRecapture.length > 0) {
3204
+ console.log(chalk.bold('Scenarios needing recapture (dependency tree changed):'));
3205
+ for (const s of scenariosNeedingRecapture) {
3206
+ const reason = s.status.status === 'impacted' && s.status.impactedBy?.length
3207
+ ? `impacted by: ${s.status.impactedBy.map((d) => `${d.name} [${d.changeType}]`).join(', ')}`
3208
+ : `${s.status.status}`;
3209
+ console.log(` ${chalk.red('✗')} ${s.scenarioName} ${chalk.dim(`(${s.entityName} — ${reason})`)}`);
3210
+ }
3211
+ console.log(chalk.yellow(' Re-register these scenarios to capture updated screenshots.'));
3212
+ console.log();
3213
+ }
3189
3214
  // Summary
3190
3215
  const allOk = summary.allPassing;
3191
3216
  if (allOk) {
@@ -3206,6 +3231,9 @@ async function handleAudit() {
3206
3231
  if (summary.functionsFailing > 0) {
3207
3232
  parts.push(`${summary.functionsFailing} function${summary.functionsFailing !== 1 ? 's' : ''} with failing tests`);
3208
3233
  }
3234
+ if (summary.functionsRunnerError > 0) {
3235
+ parts.push(`${summary.functionsRunnerError} function${summary.functionsRunnerError !== 1 ? 's' : ''} with test runner errors (not test failures — see details above)`);
3236
+ }
3209
3237
  if (summary.functionsNameMismatch > 0) {
3210
3238
  parts.push(`${summary.functionsNameMismatch} function${summary.functionsNameMismatch !== 1 ? 's' : ''} with test name mismatch (missing top-level describe)`);
3211
3239
  }
@@ -3218,6 +3246,9 @@ async function handleAudit() {
3218
3246
  if (summary.miscategorizedScenarios > 0) {
3219
3247
  parts.push(`${summary.miscategorizedScenarios} component${summary.miscategorizedScenarios !== 1 ? 's' : ''} using page URLs instead of isolation routes`);
3220
3248
  }
3249
+ if (summary.scenariosNeedingRecapture > 0) {
3250
+ parts.push(`${summary.scenariosNeedingRecapture} scenario${summary.scenariosNeedingRecapture !== 1 ? 's' : ''} need recapture`);
3251
+ }
3221
3252
  console.log(chalk.red.bold('Audit failed: ') + parts.join(', '));
3222
3253
  }
3223
3254
  console.log();
@@ -3352,6 +3383,8 @@ async function handleScenarioCoverage() {
3352
3383
  sha: e.sha,
3353
3384
  name: e.name,
3354
3385
  filePath: e.filePath || '',
3386
+ isDefaultExport: e.metadata?.notExported === false &&
3387
+ e.metadata?.namedExport === false,
3355
3388
  })));
3356
3389
  }
3357
3390
  }
@@ -4408,6 +4441,8 @@ const editorCommand = {
4408
4441
  sha: e.sha,
4409
4442
  name: e.name,
4410
4443
  filePath: e.filePath || '',
4444
+ isDefaultExport: e.metadata?.notExported === false &&
4445
+ e.metadata?.namedExport === false,
4411
4446
  })));
4412
4447
  if (result.updated > 0) {
4413
4448
  console.log(chalk.green(` Linked ${result.updated} scenario(s) to their entities`));